<!DOCTYPE html>
<html>
    <meta charset="UTF-8">

    <head>
        <style>

            *{margin: 0;padding: 0}
            body{
                width: 100%;
                height: 100%;
            }
            .pp{
                position: relative;height: 400px;width: 400px;background-color: pink
            }
            #but{width: 50px;height: 50px;background-color: black;margin-left: 500px}
            #div{width: 60px;height: 70px;background-color: #E81123;position: absolute; bottom: 0px}
        </style>
        <script>
            //继承有多种类型，1拷贝 2原型继承  3借用构造函数  4借用构造函数结合原型继承

            window.onload = function () {
//父类型
                function  Aa(name,age,he) {
                    //存放公用属性
                    this.name = name;
                    this.age = age;
                    this.he = he;
                };

                //子类型1
                function  Bb(name,age,he,stu) {
                    //call指向父类型
                    Aa.call(this,name,age,he);
                    this.stu = stu;
                };
                //子类型2
                function  Cc(name,age,he,th) {
                    Aa.call(this,name,age,he);
                    this.th = th;
                };

                Bb.prototype = new Aa();
                Bb.prototype.constructor = Bb;
                //在原型中创建Bb ”学生的“  stufool方法，
                Bb.prototype.stufool = function (){
                    console.log("学生专用老师无法访问，放在原型中所有学生可调用，且只占一处内存，若在构造函数中则会调用一次新建一份");
                };
                Cc.prototype = new Aa();
                Cc.prototype.constructor = Cc;

                var stu1 = new Bb("张一",18,173,"学生1");
                var th1 = new Cc("王老师",30,165,"老师1")
                console.dir(stu1);
                console.dir(th1);




                //函数的定义方式
                //1.函数声明 普通函数调用
                function fn1() {
                    console.log("1");
                }
                fn1();

                //2.函数表达式  方法调用
                var fn2 = function () {
                    console.log("2");
                }
                fn2();
                //函数声明与函数表达式区别:浏览器预解析时会将声明的函数提升，
                //函数表达式仅仅是将等号左边的声明提升，执行时若是调用在函数上面，则会报错


                //3.new Function 调用构造函数 不推荐，执行速度比较慢 ，
                //因为需要先解析字符串再执行。
                var fn3 = new Function('a','b','console.log(a+b)');
                fn3(1,2);


                //call bind apply

                //call
                //1 调用函数，改变函数中的this指向
                //2 第一个参数，设置函数内部this的指向
                //  其他参数对应函数内部的参数
                //3 函数的返回值 call的返回值就是函数的返回值
                //4 可以借用其他类型的方法


                //apply
                // 一般用于数组，math.max方法数组不可以使用，但是使用apply则可以将数组的
                // 内容传到math中找到最大值
                // 例
                arr = [1,2,3,4,5,6,7,8,9]
                console.log(1,2,3);
                console.log(arr);
                console.log.apply(console,arr);


                //bind
                //1 bind不会去调用方法，是复制


                // 闭包:在一个作用域中可以访问另一个作用域的变量
                // 未发生闭包
                function  fn4() {
                    var n = 10;
                    return n;
                }
                fn4();

                //发生闭包
                function  fn5() {
                    var n = 10;
                    return function (){
                        return n;
                    }
                }
                var f6 = fn5();
                console.log(f6());
                console.log(fn5()());


                //递归
                //递归就是自己调用自己,需要一个判断条件结束,否则会内存溢出报错
                //用递归的方式求一个数的乘阶
                function fn6(n) {
                    if (n === 1){
                        return 1;
                    }
                    return n * fn6(n - 1);
                }
                console.log(fn6(3));

                // 冒泡排序
                var arr1 = [9,8,7,6,5,4,6,5,44,11,22,55,84,2,4,5,85,1];
                for (var i = 0 ; i < arr1.length -1; i++){
                    for (var j = 0; j < arr1.length - (i + 1); j++){
                        if (arr1[j] > arr1[j + 1]){
                            var temp = arr1[j];
                            arr1[j] = arr1[j + 1];
                            arr1[j + 1] = temp;
                        }
                    }
                }
                console.log(arr1);

                var but = document.getElementById("but");
                but.onclick = function () {
                    startMove(100);  //调用函数
                };
            }
            var time = null;         //设置定时器time为空
            function startMove(iTarget) {   //定义一个函数
                var div = document.getElementById("div");   //获取DIV
                clearInterval(time);                        //关闭定时器
                time = setInterval(function () {            //设置定时器time
                    var speed = (iTarget - div.offsetTop)/20;//
                    if (div.offsetTop == iTarget){
                        clearInterval(time);
                    }else{
                        div.style.display = "block";
                        div.style.top = div.offsetTop + speed + 'px';
                    }
                },10);
            }

        </script>
    </head>

    <body>
        <button id="but"></button>
        <div class="pp">
            <div id="div"></div>
        </div>


    </body>
    </html>
